# Intro

This guide explains how to create a setup for running and developing the bot.
Whether you want to just run it, or also develop it and test your changes, this
guide lists the steps.

Since one of the bot's goals is provide an introductory space for Haskell, it
details all the steps of starting to work with Haskell and provides honts. Even
if you're just starting, this guide is friendly and useful to follow.

# Programming Interface

Here is a quick summary of what the bot API offers. It is being developed and
more components will probably be added.

- Bot commands with multiple prefixes and multiple names
- Reaction to various events: joins, parts, private messages, etc.
- Can run in multiple IRC channels (but on a single IRC server)
- Bot commands can run any I/O (network, files, terminal, etc.)
- Bot commands can run any IRC commands: Join, part, notice, etc.
- Persistent state can be managed by the bot commands while the bot runs
- The state includes a hierarchical central settings system
- Extra event sources: Web listener, newsfeed watcher

# Haskell

If you already have the Haskell tools installed, you can skip this section.

The bot is written in Haskell, a functional programming language. A good place
to start learning it is the
[Haskell Wikibook](https://wikibooks.org/wiki/Haskell). The definition of
Haskell is published in the form of reports, the latest being
the [Haskell 2010 Report](http://haskell.org/onlinereport/haskell2010/). While
learning, and actually in general, a very useful resource to keep open in a
browser tab is the API reference of the `base` package,
[here](http://hackage.haskell.org/package/base#module-list).

To work with Haskell you'll need 2 primary tools:

1. GHC - a compiler, interpreter, package manager and more
2. Cabal - project manager for installing packages and packaging your own

You'll need to install them both. Preferrably *GHC 7.8.4* and
*cabal-install 1.22*. If you use a Debian based distro, you can install them
easily from a [PPA](http://launchpad.net/%7Ehvr/+archive/ghc). Trisquel should
import them for you, so all you need to do is apt-get install.

For Parabola, check the versions supplied by the distro's packages.
Instructions for more distros can be found online.

Add `~/.cabal/bin:/opt/cabal/1.22/bin:/opt/ghc/7.8.4/bin` to your PATH. For
example, add this to the bottom of your `.bashrc`:

    # add haskell programs to PATH
    export PATH=~/.cabal/bin:/opt/cabal/1.22/bin:/opt/ghc/7.8.4/bin:$PATH

The Haskell community has:

- IRC channels on Freenode: `#haskell`, `#haskell-beginners`
- [Mailing lists](https://haskell.org/mailing-lists)
- A [wiki](https://wiki.haskell.org)
- [Hackage](https://hackage.haskell.org), where people upload package releases

There are 3 types of package repositories you can maintain using Cabal:

- Global repository for the system. Install there stable programs you are
  going to use. This is like like installing distro packages. What you install
  there will be available to all users on your system (if you update their
  PATH too), like with distro packages.
- User repository just for your system user. You can install there packages you
  want to experiment with, or run without installing system-wide. By default,
  this is where `cabal install`ed packages go.
- Sandbox for package development. When you use and develop various Haskell
  packages, eventually you'll encounter version conflicts. You can avoid the
  mess by installing packages into separate sandboxes. When working on several
  packages together/with consistent dependencies, they can share a sandbox.

Update your list of packages:

    $ cabal update

# Installation

You can either use a release version, or the latest development version.

Create a directory for the bot:

    $ mkdir /home/joe/bot
    $ cd /home/joe/bot

The development version many require recent dependency versions which aren't
available on Hackage yet. If building fails, it's probably because you need
those recent versions. These commands will download the dependencies most
likely to be needed. In the same way you can download more.

If you'll be using the release version, there is no need for this.

Install Darcs, a version control system. The bot itself is in a Git repository,
but some of these dependencies are in Darcs repositories. You can either
download their files using regular HTTP, e.g. with `wget`) or use Darcs. Since
Darcs is a popular version control system for Haskell projects (and is itself
written in Haskell), the latter option is demonstrated below (just change the
Darcs specific lines if you chose the former option).

If your distro has a recent enough version (preferrably 2.8.5, maybe 2.8.4 will
work too):

    $ sudo apt-get install darcs

Otherwise install Darcs from Hackage:

    $ cabal install darcs-2.8.5

Get dependency source repos if/as needed:

    $ darcs get http://hub.darcs.net/fr33domlover/irc-fun-messages/
    $ darcs get http://hub.darcs.net/fr33domlover/irc-fun-client/
    $ darcs get http://hub.darcs.net/fr33domlover/irc-fun-bot/
    $ darcs get http://hub.darcs.net/fr33domlover/settings/
    $ git clone https://notabug.org/fr33domlover/funbot-ext-events

Get the bot itself:

    $ git clone https://notabug.org/fr33domlover/funbot.git

You now have the latest development version. You can switch to the latest
release version (use `git tag --list` to find out its number), e.g.:

    $ git checkout 0.3

Now your bot directory should look like this:

    $ ls /home/joe/bot
    funbot
    funbot-ext-events
    irc-fun-bot
    irc-fun-client
    irc-fun-messages
    settings

Create a sandbox:

    $ cd funbot
    $ cabal sandbox init

In order for all the extra packages to work in the sandbox, add the local
dependencies you downloaded (if any) as sources:

    $ cabal sandbox add-source ../irc-fun-messages
    $ cabal sandbox add-source ../irc-fun-client
    $ cabal sandbox add-source ../irc-fun-bot
    $ cabal sandbox add-source ../settings
    $ cabal sandbox add-source ../funbot-ext-events

Run `cabal install --only-dependencies` and `cabal build` to build funbot and
its dependencies in the sandbox.

# Configuration

The bot has state data in JSON files and in a Haskell source file,
`src/FunBot/Config.hs`.

Create initial state data:

    $ cd funbot
    $ cp -r state-default state

In the `Config.hs` file there are safe defaults you can use as-is, but you
should probably at least change the bot's nickname. See
[here](http://hackage.haskell.org/package/irc-fun-bot/docs/Network-IRC-Fun-Bot-Types.html#t:Config)
for documentation of the config options.

    $ vim src/FunBot/Config.hs

You'll need to rebuild the bot for changes in that file to take effect.

You can also customize the event matching and behavior definitions in
`src/Main.hs`.

If you make a git commit, make sure you don't commit your personal changes to
the configuration. In particular if you set a nickname password there!

Rebuild the bot:

    $ cabal build

Some features (like channel logs and quotes) place files in separate
subdirectories.

    $ mkdir state/chanlogs state/quotes

# Running and Exploring

Now you can do things like running it, debugging it, exploring it in the REPL
(i.e. interpreter).

To run the bot:

    $ cabal run

You can also run the executable directly:

    $ dist/build/funbot/funbot

To load the source into the GHCi, the REPL, and play/explore it:

    $ cabal repl

For the explorers, there is an IRC server package in Haskell,
[hulk](http://hackage.haskell.org/package/hulk). You could run the bot against
a locally running instance of the server.

# Deployment

The Git repository contains a shell script `run.sh` you can run in a cron job.
There is also a `supervisord` configuration file. See these files for details.
If you want to run the bot as a separate system user (and not as your own
user), the steps are:

1. Create a Linux system user with its own home directory. For example,
   `/var/lib/ircbot`
2. Edit its PATH (e.g. by creating minimal `.profile` and `.bashrc`) and
   install the setup as described above. But you don't need:
   - a Cabal sandbox. You can install to the new user's user package
     repository. Simply skip the sandbox creation steps.
   - Write access to the git repo. Clone the repositories using read-only
     access. It's safer not to give this new user write access to its own code,
     just in case anything bad happens.
3. Switch to the system user in the terminal and run the bot. Edit the
   configuration source file (nickname, password, channels, etc.). Setup the
   cron job.
4. When there are updates to the bot or its dependencies, `darcs pull` or
   `git pull` them, build/install and relaunch (e.g.
   `pkill funbot && dist/build/funbot/funbot &`)

# Collaboration

There are basically 3 ways to contribute code:

- If you prefer to have your code checked by someone else for any reason, you
  can create a merge request (i.e. work in a clone or branch).
- Or create a patch with `git format-patch`
- Otherwise, this project just gives commit access to any interested community
  member / contributor.

The details follow.

## Merge Requests

The steps are:

1. Create a branch with your changes
2. Open an issue containing the URL of the branch

The branch can be in:

- The upstream funbot repository at NotABug. Feature/wip branches can be added
  as needed.
- A repository in NotABug (e.g. your personal clone of funbot) or some other
  free-software hosting platform instance online. Merge requests from
  proprietary ones, such as githu8, won't be accepted. Please use NotABug or
  GNU savannah or Rel4tion's server or your own server or some other
  free-as-in-freedom option.

## Direct Commits

This means access to pushing to the `master` branch of the upstream repository.
Ask fr33domlover.

## Patches

Open an issue in NotABugwith the patch file attached (or post a link to it, if
you host it somewhere else).
